#ifndef __MO_TYPES_H
#define __MO_TYPES_H

#include <stdint.h>
#include <cstdio>

#include "MoCommon.h"

typedef struct __MoUSBDeviceInfo
{
    int Index;                              //index of usb device
    char USBDevName[MO_MAX_DEV_NAME_LEN];   //usb device name
    char Product[32];                       //usb device product string
    char SerialNum[48];                     //usb device serial number
}MoUSBDeviceInfo;
//SUB USB device Name


typedef struct __MoStreamInfo
{
    int Index;                          //stream info index
    int ResolutionWidth;                //stream resolution : width
    int ResolutionHeight;               //stream resolution : height
    int DefaultFPS;                     //default fps
    int MaxFPS;                         //max fps
}MoStreamInfo;
//stream info

#define MO_RGB_IMAGE_TYPE_YUV422_YUYV   0x01
#define MO_RGB_IMAGE_TYPE_YUV422_YVYU   0x02

#define MO_RGB_IMAGE_TYPE_RGB888 0x03

#define MO_RGB_IMAGE_TYPE_YUV422_UYVY   0x04

#define MO_RGB_IMAGE_TYPE_YUV420_NV12    0x10   
#define MO_RGB_IMAGE_TYPE_YUV420_I420    0x20   

typedef struct __MoFrame
{
    unsigned long long TimeStamp;           //time (ms) when this frame generate
    unsigned long long FrameId;             //id of this frame
    
    unsigned int StreamType;                //image type of this frame
    unsigned int SensorId;                  //the id of the sensor that the outpout this frame
    unsigned short ResolutionWidth;         //resolution - width of this frame
    unsigned short ResolutionHeight;        //resolution - height of this frame
    unsigned int BitsPerPixel;              //bytes per pixel

    unsigned int BytesUsed;                 //frame size in bytes

    int FillLightStatus;                    //fill light status when this frame generate                  1 on, 0 off, 2(other) unknown
    int FillLightBrightness;                //fill light bright (1%~100%) when this frame generate

    int RGBImageType;

    uint8_t Reserved[64];                   //reserved 

    void *Data;                             //image data
}MoFrame;
//stream frame

static const uint16_t IMU_RECT_MATRIX_ROW = 3;
static const uint16_t IMU_RECT_MATRIX_COL = 1;
static const uint16_t IMU_RECT_MATRIX_DATA_CNT = IMU_RECT_MATRIX_ROW * IMU_RECT_MATRIX_COL;

typedef struct __MoIMUExtrinsic
{
    float matLeftR[IMU_RECT_MATRIX_DATA_CNT]  = {};
    float matLeftT[IMU_RECT_MATRIX_DATA_CNT]  = {};    
    float matRightR[IMU_RECT_MATRIX_DATA_CNT] = {};
    float matRightT[IMU_RECT_MATRIX_DATA_CNT] = {}; 
}MoIMUExtrinsic;

typedef struct __MoIMUIntrinsic
{
    float acc_n = {};  // accelerometer measurement noise standard deviation 
    float acc_w = {};  // accelerometer bias random work noise standard deviation
    float gyr_n = {};  // gyroscope measurement noise standard deviation
    float gyr_w = {};  // gyroscope bias random work noise standard deviation    
}MoIMUIntrinsic;

typedef struct __MoIMURectify
{
    MoIMUIntrinsic intrinsic;
    MoIMUExtrinsic extrinsic;    
}MoIMURectify;

typedef struct __MoIMUData
{
//    uint64_t u64ImageFrameNum;  // Corresponding Image Frame number
    uint64_t Timestamp;      // millsecond

    float Temperature;  // Celsius degree

    float LinearAccelerationX;  // meter per second^2
    float LinearAccelerationY;  // meter per second^2
    float LinearAccelerationZ;  // meter per second^2

    float AngularVelocityX;  // rad per second
    float AngularVelocityY;  // rad per second
    float AngularVelocityZ;  // rad per second
}MoIMUData;
//imu data 

typedef struct __MoMAGData
{
    uint64_t Timestamp;   // millsecond
    float Temperature;  // Celsius degree
    float MagX; 
    float MagY;  
    float MagZ;
}MoMAGData;
//mag data 


typedef struct __MoSensorData
{
    int ID;                 // sensor if, by default, the first sensor(id = 0) is a depth sensor
    int SensorType;         //sensor type, MO_SENSOR_TYPE_RGB or MO_SENSOR_TYPE_DEPTH_WITH_SIMOR
    int CmosType;           //cmos type;
    uint16_t ResWidth, ResHeight;       //resolution
}MoSensorData;

enum
{
    MO_CAM_STATUS_WORKING = 0,
    MO_CAM_STATUS_OPENED,
    MO_CAM_STATUS_NOT_INIT,
    MO_CAM_STATUS_SUSPEND,
    MO_CAM_STATUS_CLOSED
};
//camera work status



typedef struct __MoCamInfo
{
    char StreamDevName[MO_MAX_DEV_NAME_LEN];            //stream device name
    char CommDevName[MO_MAX_DEV_NAME_LEN];              //comminication device name, sometimes (use usb extension as commnicate protocol) it is the same as stream dev name
    char SerialNumber[16];                              //serial number , it is the usb device serial number not camera sn
    int  Handle;                                        //camera handle
    int  ProductType;
    int Status;                                         //camera status
}MoCamInfo;
//camera information

typedef struct __MoPoint
{
    double X;
    double Y;
    double Z;
}MoPoint;

typedef struct __MoPoint2D
{
    double x;
    double y;
}MoPoint2D;

struct MoRect
{
    uint16_t Left, Top;
    uint16_t Width, Height;
};

struct MoRectDistance
{
    uint16_t MinDisp, MaxDisp;
    uint16_t MeanDisp, MedianDisp;

    double DispDense;

    double MinDepth, MaxDepth;
    double MeanDepth, MedianDepth;

    double MeanDistance, MedianDistance;
};

//for stereo camera Intrinsics

typedef struct _mo_stereo_rectify_params 
{
    uint16_t out_width;
    uint16_t out_height;
    uint16_t virtual_img_width;
    uint16_t virtual_img_height;
    uint16_t ROI_Start_X;
    uint16_t ROI_Start_Y;
    float rectify_focus;
    float rectify_cx;
    float rectify_cy;
    float left_rectify_rotation[3];
    float right_rectify_rotation[3];
    float recitfy_bxf;
} MoStereoRectifyParams;

typedef struct _mo_mono_camera_params 
{
    float fx;
    float fy;
    float cx;
    float cy;
    float radial_distortion_k[3];
    float tangential_distortion_p[2];
} MoMonoCameraParams;

/**
 * @brief 双目基础参数
 *
 */
typedef struct _mo_binocular_camera_params {
    MoMonoCameraParams leftCamera;
    MoMonoCameraParams rightCamera;
    float rotation_r[3];
    float translation_t[3];
    uint16_t resolution_width;
    uint16_t resolution_height;
} MoBinocularCameraParams;

/**
 * @brief 双目矫正参数。与双目基础参数一起，用于双目的立体矫正。
 *
 */
typedef struct _mo_rectify_binocular_params {
    float rectify_focal_length;
    float rectify_cx;
    float rectify_cy;
    float left_rectify_rotation[3];
    float right_rectify_rotation[3];
    float baseline;
    float bxf;
    int rectify_img_width;
    int rectify_img_height;
} MoRectifyBinocularParams;

typedef struct _mo_full_stereo_camera_params 
{
    MoMonoCameraParams SimorLeftCam;
    MoMonoCameraParams SimorRightCam;
    MoMonoCameraParams IspLeftCam;
    MoMonoCameraParams IspRightCam;
    
    float rotation_r[3];
    float traslation_t[3];
    uint16_t in_width;
    uint16_t in_height;

    MoStereoRectifyParams stereo_rectify_para;
} MoFullStereoCameraParams;

struct MoCameraIntrinsics
{
    uint16_t RoiX, RoiY;
    double Cx, Cy;
    double FovX, FovY;
    double Base, Bxf;
};

#endif
